/*
 * A CORBA Generic Server
 * Part of the GICOM project
 */
package gicom;

import gicom.config.ObjectConfig;
import org.omg.CORBA.ORB;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.Servant;

public abstract class GenericObject {

    protected String id;
    
    public abstract Servant createServant ();
    
    public GenericObject () {
    }
    
    public GenericObject (String id) {
        this.id = id;
    }
    
    /**
     * Get the object id
     *
     * @return the object id
     */
    public String getId () {
        return id;
    }

    public ORB getORB () throws Exception {
        return GenericServer.defaultGenericServer.getGenericManager().getObjectORB(id);
    }
    
    public POA getPOA () throws Exception {
        return GenericServer.defaultGenericServer.getGenericManager().getObjectPOA(id);
    }
    
    public Servant getServant () throws Exception {
        return GenericServer.defaultGenericServer.getGenericManager().getObjectServant(id);
    }
    
    public org.omg.CORBA.Object getReference () throws Exception {
        return GenericServer.defaultGenericServer.getGenericManager().getObjectReference(id);
    }
    
    public void destroy () throws Exception {
        GenericServer.defaultGenericServer.getGenericManager().destroyObject(id);
    }
    
    public void destroyObject (String id) throws Exception {
        GenericServer.defaultGenericServer.getGenericManager().destroyObject(id);
    }
    
    public void createObject (ObjectConfig config) throws Exception {
        GenericServer.defaultGenericServer.getGenericManager().createObject(config);
    }
    
    protected void doPostCreate (ORB orb, POA poa) throws Exception {
        
    }
    
    protected void doPreDestroy (ORB orb, POA poa) throws Exception {
        
    }
    
    public void postCreate (final ORB orb, final POA poa) throws Exception {
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    GenericObject.this.doPostCreate(orb, poa);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    this.interrupt();
                }
            }
        };
        t.start();
        synchronized (GenericServer.defaultGenericServer.getGenericManager()) {
            while (t.isAlive()) GenericServer.defaultGenericServer.getGenericManager().wait(100);
        }
        if (t.isInterrupted()) throw new Exception("postCreate failed");
    }
    
    public void preDestroy (final ORB orb, final POA poa) throws Exception {
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    GenericObject.this.doPreDestroy(orb, poa);
                } catch (Exception ex) {
                    this.interrupt();
                }
            }
        };
        t.start();
        synchronized (GenericServer.defaultGenericServer.getGenericManager()) {
            while (t.isAlive()) GenericServer.defaultGenericServer.getGenericManager().wait(100);
        }
        if (t.isInterrupted()) throw new Exception("preDestroy failed");
    }
    
}
